// package pcaphelper
package pcaphelper

import (
	"github.com/google/gopacket/pcap"
	"github.com/pkg/errors"
)

// PcapHelper
type PcapHelper struct{ handle *pcap.Handle }

// New Create the Sniffer instance
func New(devName string) (*PcapHelper, error) {
	handle, err := pcap.OpenLive(devName, 65535, true, pcap.BlockForever)
	if err != nil {
		return nil, err
	}
	return &PcapHelper{handle}, nil
}

// Close the pcap handle
func (p *PcapHelper) Close() {
	_ = p.SetDireAndBPF(pcap.DirectionInOut, "") // 避免因为bpf导致没有捕获到任何数据包，handle将无法关闭。
	go p.handle.Close()
}

// SetDireAndBPF 设置捕获方向和 BPF 过滤
func (p *PcapHelper) SetDireAndBPF(dire pcap.Direction, bpfExpr string) error {
	if err := p.handle.SetBPFFilter(bpfExpr); err != nil {
		return errors.Wrap(err, "failed to set BPF filter")
	}
	return errors.Wrap(p.handle.SetDirection(dire), "failed to set direction")
}

// MustSetDireAndBPF 设置捕获方向和 BPF 过滤
func (p *PcapHelper) MustSetDireAndBPF(dire pcap.Direction, bpfExpr string) *PcapHelper {
	if err := p.SetDireAndBPF(dire, bpfExpr); err != nil {
		panic(err)
	}
	return p
}
